import { DataProxy } from "../A-LIB/lib.b.data";
import { AudioManager } from "../component/audio-manager";
import { APP_NAME } from "../frame.config";
import get_proxy_clock from "./data.global.clock";
import get_proxy_trigger from "./data.global.trigger";

export default class GlobalDC {
	private static _trigger_: ReturnType<typeof get_proxy_trigger>;
	private static _clock_: ReturnType<typeof get_proxy_clock>;

	public static get Trigger(){
		return GlobalDC._trigger_;
	}
	public static get Clock(){
		return GlobalDC._clock_;
	}

	public static init(){
		GlobalDC._trigger_ = get_proxy_trigger('global_trigger');
		GlobalDC._clock_ = get_proxy_clock('global_clock', APP_NAME);
		GlobalDC.clockRun();
		GlobalDC.listening();
	}

	private static listening(){
		DataProxy.follow(GlobalDC.Trigger, 'CLICK', (o, v)=>{
			AudioManager.playEffect(AudioManager.EAudio.EF_CLICK);
		}, false);
		let interval_stamp = Date.now();
		let td = 0;
		DataProxy.follow(GlobalDC.Clock, 'current_time', (o, v)=>{
			td = v - interval_stamp;
			interval_stamp = v;
			GlobalDC._interval_call_token_map_.forEach(async item=>{
				if((v - item.timestamp) >= item.interval){
					item.timestamp += item.interval;
					Reflect.apply(item.call, item.that, [td, v]);
				}
			});
		}, false);

		GlobalDC.interval(60 * 1000, (td, now)=>{
			if(mtec.time.sameDay(GlobalDC.Clock.login_time, now)){
				return void 0;
			}

			GlobalDC.Clock.login_time = now;
			GlobalDC.Trigger.NEW_DAY = now;
		});
	}

	private static clockRun(){

		let now = Date.now();
		if(!mtec.time.sameDay(GlobalDC.Clock.login_time, now)){
			GlobalDC.Clock.login_time = now;
			GlobalDC.Trigger.NEW_DAY = now;
		}

		setInterval(()=>GlobalDC.Clock.current_time = Date.now(), 1000/30);
	}

	private static _interval_call_token_map_: Map<string, {timestamp: number, interval: number, call: (td: number, now: number)=>any, that?: any}> = new Map();

	public static interval(interval: number, call: (td: number, now: number)=>any, thisArg?: any){
		let token = mtec.string.randomToken(7, 36, tlkn=>!GlobalDC._interval_call_token_map_.has(tlkn));
		GlobalDC._interval_call_token_map_.set(token, {timestamp: Date.now(), interval, call, that: thisArg??null})
		return token;
	}

	public static clearInterval(token: string){
		if(!GlobalDC._interval_call_token_map_.has(token)) return void 0;

		GlobalDC._interval_call_token_map_.delete(token);
	}
}
